home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / machserver / 1.098 / main / sun3.md / mainInit.c < prev    next >
C/C++ Source or Header  |  1991-04-08  |  12KB  |  467 lines

  1. /* 
  2.  *  main.c --
  3.  *
  4.  *    The main program for Sprite: initializes modules and creates
  5.  *    system processes. Also creates a process to run the Init program.
  6.  *
  7.  * Copyright 1986 Regents of the University of California
  8.  * All rights reserved.
  9.  */
  10.  
  11. #ifndef lint
  12. static char rcsid[] = "$Header: /sprite/src/kernel/main/sun3.md/RCS/mainInit.c,v 1.9 91/04/08 12:08:02 mgbaker Exp $ SPRITE (Berkeley)";
  13. #endif /* !lint */
  14.  
  15. #include <sprite.h>
  16. #include <dbg.h>
  17. #include <dev.h>
  18. #include <net.h>
  19. #include <fs.h>
  20. #include <fsutil.h>
  21. #include <proc.h>
  22. #include <prof.h>
  23. #include <recov.h>
  24. #include <rpc.h>
  25. #include <sched.h>
  26. #include <sig.h>
  27. #include <sync.h>
  28. #include <sys.h>
  29. #include <timer.h>
  30. #include <vm.h>
  31. #include <machMon.h>
  32. #include <devAddrs.h>
  33. #include <mach.h>
  34. #include <main.h>
  35. #include <stdio.h>
  36. #include <bstring.h>
  37. #include <string.h>
  38. #include <dump.h>
  39.  
  40. static void Init _ARGS_((void));
  41.  
  42. /*
  43.  *  Pathname of the Init program.
  44.  */
  45. #define INIT         "cmds/initsprite"
  46.  
  47. int main_PrintInitRoutines = FALSE;    /* print out each routine as
  48.                          * it's called? */
  49.  
  50. int main_PanicOK = 0;    /* Set to 1 if it's OK to panic. */
  51.  
  52.  
  53. /*
  54.  *----------------------------------------------------------------------
  55.  *
  56.  * main --
  57.  *
  58.  *    All kernel modules are initialized by calling their *_Init()
  59.  *    routines. In addition, kernel processes are created to
  60.  *    handle virtual memory and rpc-specific stuff. The last process
  61.  *    created runs the `init' program.
  62.  *
  63.  * Results:
  64.  *    None.
  65.  *
  66.  * Side effects:
  67.  *    The whole system is initialized.
  68.  *
  69.  *----------------------------------------------------------------------
  70.  */
  71.  
  72. void
  73. main()
  74. {
  75.     Proc_PID    pid;
  76.     int        i;
  77.  
  78.     /*
  79.      * Initialize variables specific to a given kernel.  
  80.      * IMPORTANT: Only variable assignments and nothing else can be
  81.      *          done in this routine.
  82.      */
  83.     Main_InitVars();
  84.  
  85.     /*
  86.      * Initialize machine dependent info.  MUST BE CALLED HERE!!!.
  87.      */
  88.     Mach_Init();
  89.     Sync_Init();
  90.  
  91.     /*
  92.      * Initialize the debugger.
  93.      */
  94.     Dbg_Init();
  95.  
  96.     /*
  97.      * Initialize the system module, particularly the fact that there is an
  98.      * implicit DISABLE_INTR on every processor.
  99.      */
  100.     if (main_PrintInitRoutines) {
  101.     Mach_MonPrintf("Calling Sys_Init().\n");
  102.     }
  103.     Sys_Init();
  104.  
  105.     /*
  106.      * Now allow memory to be allocated by the "Vm_BootAlloc" call.  Memory
  107.      * can be allocated by this method until "Vm_Init" is called.  After this
  108.      * then the normal memory allocator must be used.
  109.      */
  110.     if (main_PrintInitRoutines) {
  111.     Mach_MonPrintf("Calling Vm_BootInit().\n");
  112.     }
  113.     Vm_BootInit();
  114.  
  115.     /*
  116.      * Initialize all devices.
  117.      */
  118.     if (main_PrintInitRoutines) {
  119.     Mach_MonPrintf("Calling Dev_Init().\n");
  120.     }
  121.     Dev_Init();
  122.  
  123.     /*
  124.      *  Initialize the mappings of keys to call dump routines.
  125.      *  Must be after Dev_Init. 
  126.      */
  127.     if (main_DoDumpInit) {
  128.     if (main_PrintInitRoutines) {
  129.         Mach_MonPrintf("Calling Dump_Init().\n");
  130.     }
  131.     Dump_Init();
  132.     }
  133.  
  134.     /*
  135.      * Initialize the timer, signal, process, scheduling and synchronization
  136.      * modules' data structures.
  137.      */
  138.     if (main_PrintInitRoutines) {
  139.     Mach_MonPrintf("Calling Proc_Init().\n");
  140.     }
  141.     Proc_Init();
  142.     if (main_PrintInitRoutines) {
  143.     Mach_MonPrintf("Calling Sync_LockStatInit().\n");
  144.     }
  145.     Sync_LockStatInit();
  146.     if (main_PrintInitRoutines) {
  147.     Mach_MonPrintf("Calling Timer_Init().\n");
  148.     }
  149.     Timer_Init();
  150.     if (main_PrintInitRoutines) {
  151.     Mach_MonPrintf("Calling Sig_Init().\n");
  152.     }
  153.     Sig_Init();
  154.     if (main_PrintInitRoutines) {
  155.     Mach_MonPrintf("Calling Sched_Init().\n");
  156.     }
  157.     Sched_Init();
  158.  
  159.     /*
  160.      * Sys_Printfs are not allowed before this point.
  161.      */  
  162.     main_PanicOK++;
  163.     printf("Sprite kernel: %s\n", SpriteVersion());
  164.  
  165.     /*
  166.      * Set up bins for the memory allocator.
  167.      */
  168.     if (main_PrintInitRoutines) {
  169.     Mach_MonPrintf("Calling Fs_Bin\n");
  170.     }
  171.     Fs_Bin();
  172.     if (main_PrintInitRoutines) {
  173.     Mach_MonPrintf("Calling Net_Bin\n");
  174.     }
  175.     Net_Bin();
  176.  
  177.     /*
  178.      * Initialize virtual memory.  After this point must use the normal
  179.      * memory allocator to allocate memory.  If you use Vm_BootAlloc then
  180.      * will get a panic into the debugger.
  181.      */
  182.     if (main_PrintInitRoutines) {
  183.     Mach_MonPrintf("Calling Vm_Init\n");
  184.     }
  185.     Vm_Init();
  186.  
  187.     /*
  188.      * malloc can be called from this point on.
  189.      */
  190.  
  191.     /*
  192.      * Initialize the main process. Must be called before any new 
  193.      * processes are created.
  194.      * Dependencies: Proc_InitTable, Sched_Init, Vm_Init, Mem_Init
  195.      */
  196.     if (main_PrintInitRoutines) {
  197.     Mach_MonPrintf("Calling Proc_InitMainProc\n");
  198.     }
  199.     Proc_InitMainProc();
  200.  
  201.     /*
  202.      * Initialize the network and the routes.  It would be nice if we
  203.      * could call Net_Init earlier so that we can use the debugger earlier
  204.      * but we must call Vm_Init first.  VM could be changed so that we
  205.      * could move the call earlier however.
  206.      */
  207.     if (main_PrintInitRoutines) {
  208.     Mach_MonPrintf("Calling Net_Init\n");
  209.     }
  210.     Net_Init();
  211.     if (main_PrintInitRoutines) {
  212.     Mach_MonPrintf("Calling Net_RouteInit\n");
  213.     }
  214.     Net_RouteInit();
  215.  
  216.     /*
  217.      * Enable server process manager.
  218.      */
  219.     if (main_PrintInitRoutines) {
  220.     Mach_MonPrintf("Calling Proc_ServerInit\n");
  221.     }
  222.     Proc_ServerInit();
  223.  
  224.     /*
  225.      * Initialize the recovery module.  Do before Rpc and after Vm_Init.
  226.      */
  227.     if (main_PrintInitRoutines) {
  228.     Mach_MonPrintf("Calling Recov_Init\n");
  229.     }
  230.     Recov_Init();
  231.  
  232.     /*
  233.      * Initialize the data structures for the Rpc system.  This uses
  234.      * Vm_RawAlloc to so it must be called after Vm_Init.
  235.      * Dependencies: Timer_Init, Vm_Init, Net_Init, Recov_Init
  236.      */
  237.     if (main_PrintInitRoutines) {
  238.     Mach_MonPrintf("Calling Rpc_Init\n");
  239.     }
  240.     Rpc_Init();
  241.  
  242.     /*
  243.      * Configure devices that may or may not exist.  This needs to be
  244.      * done after Proc_InitMainProc because the initialization routines
  245.      * use SetJump which uses the proc table entry for the main process.
  246.      */
  247.     if (main_PrintInitRoutines) {
  248.     Mach_MonPrintf("Calling Dev_Config\n");
  249.     }
  250.     Dev_Config();
  251.  
  252.     /*
  253.      * Initialize profiling after the timer and vm stuff is set up.
  254.      * Dependencies: Timer_Init, Vm_Init
  255.      */
  256.     if (main_DoProf) {
  257.     Prof_Init();
  258.     }
  259.     /*
  260.      *  Allow interrupts from now on.
  261.      */
  262.     if (main_PrintInitRoutines) {
  263.     Mach_MonPrintf("Enabling interrupts\n");
  264.     }
  265.     ENABLE_INTR();
  266.  
  267.     if (main_Debug) {
  268.     DBG_CALL;
  269.     }
  270.  
  271.     /*
  272.      * Sleep for a few seconds to calibrate the idle time ticks.
  273.      */
  274.     Sched_TimeTicks();
  275.  
  276.     /*
  277.      * Start profiling, if desired.
  278.      */
  279.     if (main_DoProf) {
  280.         (void) Prof_Start();
  281.     }
  282.  
  283.     /*
  284.      * Do an initial RPC to get a boot timestamp.  This allows
  285.      * servers to detect when we crash and reboot.  This will set the
  286.      * system clock too, although rdate is usually done from user level later.
  287.      */
  288.     if (main_PrintInitRoutines) {
  289.     Mach_MonPrintf("Call Rpc_Start\n");
  290.     }
  291.     Rpc_Start();
  292.  
  293.     /*
  294.      * Initialize the file system. 
  295.      */
  296.     if (main_PrintInitRoutines) {
  297.     Mach_MonPrintf("Call Fs_Init\n");
  298.     }
  299.     Fs_Init();
  300.  
  301.     /*
  302.      * Before starting up any more processes get a current directory
  303.      * for the main process.  Subsequent new procs will inherit it.
  304.      */
  305.     if (main_PrintInitRoutines) {
  306.     Mach_MonPrintf("Call Fs_ProcInit\n");
  307.     }
  308.     Fs_ProcInit();
  309.     if (main_PrintInitRoutines) {
  310.     Mach_MonPrintf("Bunch of call funcs\n");
  311.     }
  312.     /*
  313.      * Start the clock daemon and the routine that opens up the swap directory.
  314.      */
  315.     Proc_CallFunc(Vm_Clock, (ClientData) NIL, 0);
  316.     Proc_CallFunc(Vm_OpenSwapDirectory, (ClientData) NIL, 0);
  317.  
  318.     /*
  319.      * Start the process that synchronizes the filesystem caches
  320.      * with the data kept on disk.
  321.      */
  322.     Proc_CallFunc(Fsutil_SyncProc, (ClientData) NIL, 0);
  323.  
  324.     /*
  325.      * Create a few RPC server processes and the Rpc_Daemon process which
  326.      * will create more server processes if needed.
  327.      */
  328.     if (main_NumRpcServers > 0) {
  329.     for (i=0 ; i<main_NumRpcServers ; i++) {
  330.         (void) Rpc_CreateServer((int *) &pid);
  331.     }
  332.     }
  333.     (void) Proc_NewProc((Address) Rpc_Daemon, PROC_KERNEL, FALSE, &pid,
  334.     "Rpc_Daemon");
  335.     if (main_PrintInitRoutines) {
  336.     Mach_MonPrintf("Creating Proc server procs\n");
  337.     }
  338.  
  339.     /*
  340.      * Create processes  to execute functions.
  341.      */
  342.     for (i = 0; i < proc_NumServers; i++) {
  343.     (void) Proc_NewProc((Address) Proc_ServerProc, PROC_KERNEL, FALSE, 
  344.             &pid, "Proc_ServerProc");
  345.     }
  346.  
  347.     /*
  348.      * Create a recovery process to monitor other hosts.  Can't use
  349.      * Proc_CallFunc's to do this because they can be used up waiting
  350.      * for page faults against down servers.  (Alternatively the VM
  351.      * code could be fixed up to retry page faults later instead of
  352.      * letting the Proc_ServerProc wait for recovery.)
  353.      */
  354.     (void) Proc_NewProc((Address) Recov_Proc, PROC_KERNEL, FALSE, &pid,
  355.             "Recov_Proc");
  356.  
  357.     /*
  358.      * Set up process migration recovery management.
  359.      */
  360.     if (main_PrintInitRoutines) {
  361.     Mach_MonPrintf("Calling Proc_MigInit\n");
  362.     }
  363.     Proc_MigInit();
  364.  
  365.     /*
  366.      * Call the routine to start test kernel processes.
  367.      */
  368.  
  369.     if (main_PrintInitRoutines) {
  370.     Mach_MonPrintf("Calling Main_HookRoutine\n");
  371.     }
  372.     Main_HookRoutine();
  373.  
  374.     /*
  375.      * Print out the amount of memory used.
  376.      */
  377.     printf("MEMORY %d bytes allocated for kernel\n", 
  378.         vmMemEnd - mach_KernStart);
  379.  
  380.     /*
  381.      * Start up the first user process.
  382.      */
  383.     if (main_PrintInitRoutines) {
  384.     Mach_MonPrintf("Creating Init\n");
  385.     }
  386.     (void) Proc_NewProc((Address) Init, PROC_KERNEL, FALSE, &pid, "Init");
  387.  
  388.     (void) Sync_WaitTime(time_OneYear);
  389.     printf("Main exiting\n");
  390.     Proc_Exit(0);
  391. }
  392.  
  393.  
  394. /*
  395.  *----------------------------------------------------------------------
  396.  *
  397.  * Init --
  398.  *
  399.  *    This routine execs the init program.
  400.  *
  401.  * Results:
  402.  *    This routine only returns an error if the exec failed.
  403.  *
  404.  * Side effects:
  405.  *    The current process image is overlayed by the init process.
  406.  *
  407.  *----------------------------------------------------------------------
  408.  */
  409. static void
  410. Init()
  411. {
  412.     char        *initArgs[10];
  413.     ReturnStatus    status;
  414.     char        argBuffer[100];
  415.     int            argc;
  416.     Fs_Stream        *dummy;
  417.     char        bootCommand[103];
  418.     char        *ptr;
  419.     int            i;
  420.     int            argLength;
  421.  
  422.     if (main_PrintInitRoutines) {
  423.     Mach_MonPrintf("In Init\n");
  424.     }
  425.     bzero(bootCommand, 103);
  426.     argc = Mach_GetBootArgs(8, 100, &(initArgs[2]), argBuffer);
  427.     if (argc > 0) {
  428.     argLength = (((int) initArgs[argc+1]) + strlen(initArgs[argc+1]) +
  429.             1 - ((int) argBuffer));
  430.     } else {
  431.     argLength = 0;
  432.     }
  433.     if (argLength > 0) {
  434.     initArgs[1] = "-b";
  435.     ptr = bootCommand;
  436.     for (i = 0; i < argLength; i++) {
  437.         if (argBuffer[i] == '\0') {
  438.         *ptr++ = ' ';
  439.         } else {
  440.         *ptr++ = argBuffer[i];
  441.         }
  442.     }
  443.     bootCommand[argLength] = '\0';
  444.     initArgs[2] = bootCommand;
  445.     initArgs[argc + 2] = (char *) NIL;
  446.     } else {
  447.     initArgs[1] = (char *) NIL;
  448.     }
  449.     if (main_AltInit != 0) {
  450.     initArgs[0] = main_AltInit;
  451.     printf("Execing \"%s\"\n", initArgs[0]);
  452.     status = Proc_KernExec(initArgs[0], initArgs);
  453.     printf( "Init: Could not exec %s status %x.\n",
  454.             initArgs[0], status);
  455.     }
  456.     status = Fs_Open(INIT,FS_EXECUTE | FS_FOLLOW, FS_FILE, 0, &dummy);
  457.     if (status != SUCCESS) {
  458.     printf("Can't open %s <0x%x>\n", INIT,status);
  459.     }
  460.     initArgs[0] = INIT;
  461.     status = Proc_KernExec(initArgs[0], initArgs);
  462.     printf( "Init: Could not exec %s status %x.\n",
  463.             initArgs[0], status);
  464.     Proc_Exit(1);
  465. }
  466.  
  467.